package com.pkk.penguin.frame.know.java.Javacoreknowledge.thread.threadpool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.SneakyThrows;
import org.junit.Test;

/**
 * @author peikunkun
 * @version V1.0
 * @date 2020-08-21 14:59
 * @since 公共线程池的使用
 **/
public class ComonThreadPool1 {


  /**
   * 域名检测池核心线程
   */
  private static final Integer CHECK_DOMAIN_THREAD_CORE = 2;
  /**
   * 最大线程数量
   */
  private static final Integer CHECK_DOMAIN_THREAD_MAX = 4;
  /**
   * 空闲线程(#CHECK_DOMAIN_THREAD_MAX-#CHECK_DOMAIN_THREAD_CORE)的空闲线程保留时间
   */
  private static final Integer CHECK_DOMAIN_THREAD_KEEP_ALIVE = 1;

  /**
   * 最大允许队列等待的任务数
   */
  private static final Integer CHECK_DOMAIN_THREAD_MAX_TASK = 1;
  private static final BlockingQueue<Runnable> CHECK_DOMAIN_THREAD_QUEUE = new ArrayBlockingQueue<Runnable>(
      CHECK_DOMAIN_THREAD_MAX_TASK, Boolean.TRUE);

  /**
   * 检测的公共线程
   */
  public static ThreadPoolExecutor CHECK_DOMAIN_THREAD = new ThreadPoolExecutor(CHECK_DOMAIN_THREAD_CORE,
      CHECK_DOMAIN_THREAD_MAX, CHECK_DOMAIN_THREAD_KEEP_ALIVE, TimeUnit.SECONDS, CHECK_DOMAIN_THREAD_QUEUE,
      new ThreadFactory() {
        /**
         * Constructs a new {@code Thread}.  Implementations may also initialize priority, name, daemon status,
         * {@code ThreadGroup}, etc.
         *
         * @param r a runnable to be executed by new thread instance
         * @return constructed thread, or {@code null} if the request to create a thread is rejected
         */
        @Override
        public Thread newThread(Runnable r) {
          return new Thread(r, "ZhiYi-CheckDomain-" + r.hashCode());
        }
        //如果线程还是不够用,那就谁发起的谁执行吧（交给调用者线程执行(主线程)）
      }, new ThreadPoolExecutor.CallerRunsPolicy());


  @Test
  public void Administrator_62_20200821152406_ThreadPool() throws InterruptedException {
    System.out.println("欢迎使用单元测试方法【Administrator_62()_20200821152406】");
    System.out.println("此方法测试描述：【】");

    final Thread thread = new Thread(new Runnable() {
      /**
       * When an object implementing interface <code>Runnable</code> is used to create a thread, starting the
       * thread causes the object's
       * <code>run</code> method to be called in that separately executing
       * thread.
       * <p>
       * The general contract of the method <code>run</code> is that it may take any action whatsoever.
       *
       * @see Thread#run()
       */
      @Override
      public void run() {
        for (int i = 0; i < 20; i++) {
          CHECK_DOMAIN_THREAD.submit(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
              System.out.println(Thread.currentThread().getName() + " is Running as 1");
              Thread.sleep(1000L);
            }
          });
      /*CHECK_DOMAIN_THREAD.execute(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
          System.out.println(Thread.currentThread().getName() + " is Running");
          Thread.sleep(1000L);
        }
      });*/
        }
      }
    });

    final Thread thread1 = new Thread(new Runnable() {
      /**
       * When an object implementing interface <code>Runnable</code> is used to create a thread, starting the
       * thread causes the object's
       * <code>run</code> method to be called in that separately executing
       * thread.
       * <p>
       * The general contract of the method <code>run</code> is that it may take any action whatsoever.
       *
       * @see Thread#run()
       */
      @Override
      public void run() {
        for (int i = 0; i < 20; i++) {
          CHECK_DOMAIN_THREAD.submit(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
              System.out.println(Thread.currentThread().getName() + " is Running as 2");
              Thread.sleep(1000L);
            }
          });
      /*CHECK_DOMAIN_THREAD.execute(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
          System.out.println(Thread.currentThread().getName() + " is Running");
          Thread.sleep(1000L);
        }
      });*/
        }
      }
    });

    thread.start();
    thread1.start();
    System.out.println("主线程开始执行了");
    Thread.sleep(60000L);

  }

}
